package com.phs.main.config;

import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Profile;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.service.*;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spi.service.contexts.SecurityContext;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;

import java.util.ArrayList;
import java.util.List;

/**
 * Swagger2的接口配置
 *
 * <p> @Api：修饰整个类，描述Controller的作用</p>
 * <p> @ApiOperation：描述一个类的一个方法，或者说一个接口</p>
 * <p> @ApiParam：单个参数描述</p>
 * <p> @ApiModel：用对象来接收参数</p>
 * <p> @ApiProperty：用对象接收参数时，描述对象的一个字段</p>
 * <p> @ApiResponse：HTTP响应其中1个描述</p>
 * <p> @ApiResponses：HTTP响应整体描述</p>
 * <p> @ApiIgnore：使用该注解忽略这个API</p>
 * <p> @ApiError:：发生错误返回的信息</p>
 * <p> @ApiImplicitParam：描述一个请求参数，可以配置参数的中文含义，还可以给参数设置默认值</p>
 * <p> @ApiImplicitParams：描述由多个 @ApiImplicitParam 注解的参数组成的请求参数列表</p>
 */
@Configuration
@EnableSwagger2
@Profile("dev")
public class SwaggerConfig {

	/**
	 * 创建API
	 */
	@Bean
	public Docket createRestApi() {
		return new Docket(DocumentationType.SWAGGER_2)
				// 是否启用Swagger
//				.enable(enabled)
				// 用来创建该API的基本信息，展示在文档的页面中（自定义展示的信息）
				.apiInfo(apiInfo())
				// 设置哪些接口暴露给Swagger展示
				.select()
				// 扫描所有有注解的api，用这种方式更灵活
				.apis(RequestHandlerSelectors.withClassAnnotation(Api.class))
				.apis(RequestHandlerSelectors.withMethodAnnotation(ApiOperation.class))
				// 扫描所有 .apis(RequestHandlerSelectors.any())
				.paths(PathSelectors.any())
				.build()
				/* 设置安全模式，swagger可以设置访问token */
				.securitySchemes(securitySchemes())
				.securityContexts(securityContexts());
	}

	/**
	 * 安全模式，这里指定token通过Authorization头请求头传递
	 */
	private List<ApiKey> securitySchemes() {
		List<ApiKey> apiKeyList = new ArrayList<>();
		apiKeyList.add(new ApiKey("Authorization", "Authorization", "header"));
		return apiKeyList;
	}

	/**
	 * 安全上下文
	 */
	private List<SecurityContext> securityContexts() {
		List<SecurityContext> securityContexts = new ArrayList<>();
		securityContexts.add(
				SecurityContext.builder()
						.securityReferences(defaultAuth())
						.forPaths(PathSelectors.regex("^(?!auth).*$"))
						.build());
		return securityContexts;
	}

	/**
	 * 默认的安全上引用
	 */
	private List<SecurityReference> defaultAuth() {
		AuthorizationScope authorizationScope = new AuthorizationScope("global", "accessEverything");
		AuthorizationScope[] authorizationScopes = new AuthorizationScope[1];
		authorizationScopes[0] = authorizationScope;
		List<SecurityReference> securityReferences = new ArrayList<>();
		securityReferences.add(new SecurityReference("Authorization", authorizationScopes));
		return securityReferences;
	}

	/**
	 * 添加摘要信息
	 */
	private ApiInfo apiInfo() {
		// 用ApiInfoBuilder进行定制
		return new ApiInfoBuilder()
				.title("RESTful APIs")
				.description("后端API")
				.contact(new Contact("phs",
						"https://gitee.com/kvtll/PropertyManagementSystem",
						""))
				.version("1.0")
				.build();
	}
}
